#ifndef _TBCOLOR_H_
#define _TBCOLOR_H_

#include "TBSettings.h"

#include "TBPixel.h"
#include "TBMath.h"

namespace tb
{

	class ColorHSV;

	class TB_DLL_FUNC ColorRGB
	{

	public:

		// ================================
		// Static methods
		// ================================

		static ColorRGB _RANDOM();
		static ColorRGB _BLACK;
		static ColorRGB _WHITE;
		static ColorRGB _RED;
		static ColorRGB _GREEN;
		static ColorRGB _BLUE;
		static ColorRGB _YELLOW;

		// ================================
		// Constructors
		// ================================

		ColorRGB();
		ColorRGB(float a_RGB, float a_Alpha = 1.f);
		ColorRGB(float a_R, float a_G, float a_B, float a_A = 1.f);
		ColorRGB(Pixel a_Color);
		ColorRGB(const ColorRGB& a_Other);
		~ColorRGB();

		// ================================
		// Conversion
		// ================================

		ColorRGB& FromHTML(const char* a_HTMLColor);
		ColorRGB& FromPixel(const Pixel& a_Pixel);

		ColorRGB& ToOpenGLColor(float* a_Target);
		Pixel ToPixel() const;

		// ================================
		// Assignment & Access
		// ================================

		ColorRGB& operator = (Pixel a_Color);
		ColorRGB& operator = (const ColorRGB& a_Other);
		ColorRGB& operator = (float a_Scalar);

		float& operator [] (int a_Index);
		float operator [] (int a_Index) const;

		// ================================
		// Operators
		// ================================

		ColorRGB& operator += (const ColorRGB& a_Other);
		ColorRGB& operator += (Pixel a_Color);
		ColorRGB& operator += (float a_Scalar);
		ColorRGB operator + (const ColorRGB& a_Other) const;
		ColorRGB operator + (float a_Scalar) const;

		ColorRGB& operator -= (const ColorRGB& a_Other);
		ColorRGB& operator -= (float a_Scalar);
		ColorRGB operator - (const ColorRGB& a_Other) const;
		ColorRGB operator - (float a_Scalar) const;

		ColorRGB& operator *= (const ColorRGB& a_Other);
		ColorRGB& operator *= (float a_Scalar);
		ColorRGB operator * (const ColorRGB& a_Other) const;
		ColorRGB operator * (float a_Scalar) const;

		ColorRGB& operator /= (const ColorRGB& a_Other);
		ColorRGB& operator /= (float a_Scalar);
		ColorRGB operator / (const ColorRGB& a_Other) const;
		ColorRGB operator / (float a_Scalar) const;

		// ================================
		// Functions
		// ================================

		ColorRGB& Clear();

		float GetLength() const;

		ColorRGB& Blend(const ColorRGB& a_Other, float a_Percentage);
		ColorRGB GetBlended(const ColorRGB& a_Other, float a_Percentage) const;

		ColorRGB& Normalize();
		ColorRGB GetNormalized() const;

		ColorRGB& ClampUp(float a_Upper = 1.f);
		ColorRGB& ClampDown(float a_Lower = 0.f);
		ColorRGB& Clamp(float a_Lower = 0.f, float a_Upper = 1.f);

		// ================================
		// Data
		// ================================

		float r, g, b, a;	

	}; // class ColorRGB

	typedef ColorRGB Color;

	class TB_DLL_FUNC ColorHSV
	{

	public:

		// ================================
		// Constructors
		// ================================

		ColorHSV();
		ColorHSV(float a_Hue, float a_Saturation, float a_Value);
		ColorHSV(const ColorRGB& a_Color);

		// ================================
		// Conversion
		// ================================

		ColorHSV& FromRGB(const ColorRGB& a_RGB);

		ColorRGB ToRGB();

		// ================================
		// Data
		// ================================

		float hue, saturation, value;

	}; // class ColorHSV

}; // namespace tb

#include "TBColor.inl"

#endif